#include <iostream>
#include <sstream>
#include <vector>

#include <functional>
#include <boost/bind.hpp>

#include <ftw.h>
#include <errno.h>
#include <unistd.h>

#include "page_type.h"
#include "page_info.h"

namespace jsearch
{

struct page_info::Impl
{
	public:
		Impl(int id, int type, std::string name)
			:page_id(id), page_type(type),page_name(name)
		{
			if (id<0 || name.empty()) {
				std::cerr<<"error:class page_info initial value is invalid"
					<<std::endl;
				exit(1);
			}
		}

		Impl(std::string db_fmt)
		{
			if (db_fmt=="")	{
				std::cerr<<"error:db_fmt format is not valid"<<std::endl;
				exit(1);
			}

			std::stringstream fmt(db_fmt);
			fmt>>page_id;
			fmt>>page_type;
			fmt>>page_name;

			if (fmt.fail())	{
				std::cerr<<"page_info format error"<<std::endl;
				fmt.clear();
			}
		}

		int id() const
		{
			return page_id;
		}

		int type() const
		{
			return page_type;
		}

		std::string name() const 
		{
			return page_name;
		}

		friend std::ostream& operator<< (std::ostream& os, const Impl& pi)
		{
			os<<pi.db_format();
			os.clear();

			return os;
		}


	private:
		std::string db_format() const
		{
			std::stringstream sfmt;
			std::string delim = " ";

			sfmt<<page_id<<delim;
			sfmt<<page_type<<delim;

			if (page_name.empty()) {
				std::cerr<<"error:page_name is null"<<std::endl;
				return "";
			} else {
				sfmt<<page_name<<std::endl;
			}

			if (sfmt.fail()) {
				std::cerr<<"error:db_formt error"<<std::endl;
				sfmt.clear();
				return "";
			}

			return sfmt.str();
		}

	private:
		int           page_id;
		int           page_type;
		std::string   page_name;
};


page_info::page_info(int id, int type, std::string name)
:pimpl( new Impl(id,type,name))
{ }

page_info::page_info(std::string db_fmt)
:pimpl( new Impl(db_fmt))
{ }

std::ostream& operator<< (std::ostream& os, const page_info& pi)
{ 
	os<<*pi.pimpl; 
	return os;
}

int page_info::id() const
{
	return pimpl->id();
}

int page_info::type() const
{
	return pimpl->type();
}

std::string page_info::name() const
{
	return pimpl->name();
}

}//end namespace
